/**
 * 通用工具函数
 */

/**
 * 深拷贝
 * @param obj 要拷贝的对象
 * @returns any
 */
export function deepClone<T>(obj: T): T {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  if (obj instanceof Date) {
    return new Date(obj.getTime()) as T
  }

  if (obj instanceof RegExp) {
    return new RegExp(obj) as T
  }

  if (Array.isArray(obj)) {
    return obj.map(item => deepClone(item)) as T
  }

  const cloned = {} as T
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      cloned[key] = deepClone(obj[key])
    }
  }
  return cloned
}

/**
 * 防抖函数
 * @param fn 要执行的函数
 * @param delay 延迟时间
 * @returns Function
 */
export function debounce<T extends (...args: any[]) => any>(fn: T, delay: number) {
  let timer: number | null = null
  return function (this: any, ...args: Parameters<T>) {
    if (timer)
      clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay) as unknown as number
  }
}

/**
 * 节流函数
 * @param fn 要执行的函数
 * @param delay 延迟时间
 * @returns Function
 */
export function throttle<T extends (...args: any[]) => any>(fn: T, delay: number) {
  let last = 0
  return function (this: any, ...args: Parameters<T>) {
    const now = Date.now()
    if (now - last >= delay) {
      fn.apply(this, args)
      last = now
    }
  }
}

/**
 * 随机生成指定范围的数字
 * @param min 最小值
 * @param max 最大值
 * @returns number
 */
export function random(min: number, max: number): number {
  return Math.floor(Math.random() * (max - min + 1) + min)
}

/**
 * 获取URL参数
 * @param url URL字符串
 * @returns object
 */
export function getUrlParams(url: string): Record<string, string> {
  const params: Record<string, string> = {}
  const search = url.split('?')[1]
  if (!search)
    return params

  search.split('&').forEach((item) => {
    const [key, value] = item.split('=')
    params[key] = decodeURIComponent(value)
  })
  return params
}

/**
 * 等待指定时间
 * @param ms 毫秒
 * @returns Promise
 */
export function sleep(ms: number): Promise<void> {
  return new Promise(resolve => setTimeout(resolve, ms))
}

/**
 * 获取数据类型
 * @param value 要判断的值
 * @returns string
 */
export function getType(value: unknown): string {
  return Object.prototype.toString.call(value).slice(8, -1).toLowerCase()
}

/**
 * 随机生成指定长度的ID
 * @param length ID的长度
 * @returns string
 */
export function randomId(length: number): string {
  let result = ''
  const characters = 'abcdefghijklmnopqrstuvwxyz0123456789'
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * characters.length))
  }
  return result
}
